import logging
import json
from logging.handlers import TimedRotatingFileHandler

DEBUG = logging.DEBUG
INFO = logging.INFO


class LogConfig:
    __has_init = False

    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            cls._instance = object.__new__(cls)
        return cls._instance

    def __init__(
        self,
        formats=None,
        level=DEBUG,
        is_stream=True,
        log_path='log.txt',
    ):
        if self.__has_init:
            return
        self.__has_init = True

        self.level = level
        self.is_stream = is_stream
        self.log_path = self.path = log_path
        if formats:
            self.formats = formats
        else:
            self.formats = json.dumps({
                "time": "%(asctime)s",
                "name": "%(name)s",
                "file": "%(pathname)s[line:%(lineno)d]",
                "level": "%(levelname)s",
                "msg": "%(message)s"
            })


class LogHandler(logging.Logger):
    def __init__(self, name) -> None:
        config = LogConfig()
        logging.Logger.__init__(self, name, level=config.level)

        self.name = name
        self.level = config.level

        self.formatter = logging.Formatter(config.formats)
        if config.is_stream:
            self.__setStreamHandler__()
        else:
            self.log_path = config.log_path
            self.__setFileHandler__()

    def __setStreamHandler__(self):
        """
        set stream handler
        :param level:
        :return:
        """
        stream_handler = logging.StreamHandler()
        stream_handler.setFormatter(self.formatter)
        stream_handler.setLevel(self.level)

        self.addHandler(stream_handler)

    def __setFileHandler__(self):
        """
        set file handler
        :param level:
        :return:
        """

        # 设置日志回滚, 保存在log目录, 一天保存一个文件, 保留15天
        file_name = self.log_path
        file_handler = TimedRotatingFileHandler(filename=file_name,
                                                when='D',
                                                interval=1,
                                                backupCount=15)

        file_handler.suffix = '%Y%m%d.log'  # type: ignore

        file_handler.setLevel(self.level)

        file_handler.setFormatter(self.formatter)
        self.file_handler = file_handler
        self.addHandler(file_handler)


if __name__ == "__main__":
    # configA = LogConfig(is_stream=False)  # file
    configB = LogConfig(level=10, is_stream=True)  # file

    log = LogHandler('test')
    log.debug('is a debug msg')
    log.info('is a info msg')
    log.warning('is a warning msg')
